# evaluator/generate_report.py (最终完整版)

import json
from dataclasses import dataclass, asdict
from typing import List, Optional, Dict, Any
from openai import OpenAI
from django.conf import settings

# 从Django设置中获取API密钥
api_key = getattr(settings, 'XINGHUO_API_KEY', 'YOUR_API_KEY_HERE')

# ==============================================================================
# 1. 前端数据结构定义 (与您提供的代码一致)
# ==============================================================================

@dataclass
class CandidateSummary:
    candidate_name: str
    match_score: float
    core_skills_matched: List[str]
    soft_skills_detected: List[str]
    education_summary: str
    experience_summary: str
    resume_file_url: str
    interview_recommendation: str
    highlights: Optional[List[str]] = None

    def to_dict(self):
        data = asdict(self)
        data['highlights'] = data['highlights'] or []
        return data

@dataclass
class FeedbackItem:
    dimension: str
    score: float
    max_score: float
    comments: str

    def to_dict(self):
        return asdict(self)

@dataclass
class ScreeningResult:
    passed: bool
    final_score: float
    threshold_score: float
    feedback: List[FeedbackItem]
    suggestions: List[str]

    def to_dict(self):
        return {
            "passed": self.passed,
            "final_score": self.final_score,
            "threshold_score": self.threshold_score,
            "feedback": [item.to_dict() for item in self.feedback],
            "suggestions": self.suggestions
        }

# ==============================================================================
# 2. [新增] 调用AI生成洞察报告的函数
# ==============================================================================

def _call_ai_for_report_summary(
    unified_jd: Dict[str, Any],
    unified_resume: Dict[str, Any],
    matcher_result: Dict[str, Any]
) -> Dict[str, Any]:
    """
    当候选人通过筛选后，调用AI生成一份有洞察力的摘要报告。
    """
    client = OpenAI(api_key=api_key, base_url="https://dashscope.aliyuncs.com/compatible-mode/v1")
    
    # 步骤 1: 将Python字典转换为格式化的JSON字符串
    jd_str = json.dumps(unified_jd, ensure_ascii=False, indent=2)
    resume_str = json.dumps(unified_resume, ensure_ascii=False, indent=2)
    match_str = json.dumps({
        "total_score": f"{matcher_result.get('total_score', 0)*100:.1f}/100",
        "dimension_scores": {k: f"{v*100:.1f}/100" for k, v in matcher_result.get('details', {}).items()},
        "weights_used": matcher_result.get('weights_used', {})
    }, ensure_ascii=False, indent=2)

    # 步骤 2: 构建给AI的Prompt
    prompt = f"""
    你是一位顶级的招聘总监，眼光毒辣，语言精练。现在，你需要根据以下三份信息，为一位通过初步筛选的候选人撰写一份简明扼要的筛选报告。

    ---
    ### 1. 职位要求 (JD)
    ```json
    {jd_str}
    ```

    ### 2. 候选人档案 (Resume)
    ```json
    {resume_str}
    ```

    ### 3. 量化匹配分析结果
    ```json
    {match_str}
    ```

    请根据以上信息，生成以下结构化报告（JSON格式）：

    {{
        "candidate_name": "候选人姓名",
        "match_score": 匹配分数（0-100的整数）,
        "core_skills_matched": ["匹配的核心技能列表"],
        "soft_skills_detected": ["检测到的软技能列表"],
        "education_summary": "教育背景摘要（一句话）",
        "experience_summary": "工作经验摘要（一句话）",
        "interview_recommendation": "面试推荐（'推荐进入面试'/'有条件推荐'/'暂不推荐'）",
        "highlights": ["候选人亮点1", "候选人亮点2", "候选人亮点3"]
    }}

    注意：
    1. 只输出JSON格式，不要添加任何解释
    2. match_score应该是0-100的整数
    3. 所有数组字段至少包含1个元素
    4. 摘要要简洁明了，突出重点
    """

    try:
        completion = client.chat.completions.create(
            model="qwen-plus",
            messages=[
                {"role": "system", "content": "你是一位专业的招聘分析师，擅长生成结构化的候选人评估报告。"},
                {"role": "user", "content": prompt}
            ],
            temperature=0.3
        )
        content = completion.choices[0].message.content.strip()
        
        # 清理可能的Markdown标记
        if content.startswith("```json"):
            content = content[7:].strip()
        if content.endswith("```"):
            content = content[:-3].strip()
            
        return json.loads(content)
    except Exception as e:
        print(f"AI报告生成失败: {e}")
        # 返回默认报告
        return {
            "candidate_name": "未知",
            "match_score": int(matcher_result.get('total_score', 0) * 100),
            "core_skills_matched": ["技能匹配分析中"],
            "soft_skills_detected": ["软技能分析中"],
            "education_summary": "教育背景分析中",
            "experience_summary": "工作经验分析中",
            "interview_recommendation": "recommended" if matcher_result.get('total_score', 0) >= 0.7 else "not_recommended",
            "highlights": ["候选人分析中"]
        }

# ==============================================================================
# 3. 主报告生成函数
# ==============================================================================

def generate_report(
    matcher_result: Dict[str, Any],
    unified_resume: Dict[str, Any],
    unified_jd: Dict[str, Any], # [新增] 需要传入JD信息以供AI分析
    resume_url: str,
    threshold_score: float = 70.0
    ) -> dict:
    """
    生成最终的筛选报告。
    """
    final_score = matcher_result.get('total_score', 0) * 100  # 转换为百分比
    passed = final_score >= threshold_score

    if passed:
        return _create_passed_report(
            final_score, threshold_score, matcher_result, 
            unified_resume, unified_jd, resume_url
        )
    else:
        return _create_failed_report(
            final_score, threshold_score, matcher_result
        )

def _create_passed_report(
    final_score: float,
    threshold_score: float,
    matcher_result: Dict[str, Any],
    unified_resume: Dict[str, Any],
    unified_jd: Dict[str, Any],
    resume_url: str
    ) -> dict:
    """创建通过筛选的报告"""
    
    # 调用AI生成候选人摘要
    ai_summary = _call_ai_for_report_summary(unified_jd, unified_resume, matcher_result)
    
    # 构建反馈项目
    feedback_items = []
    for dimension, score in matcher_result.get('details', {}).items():
        feedback_items.append(FeedbackItem(
            dimension=dimension,
            score=score * 100,  # 转换为百分比
            max_score=100.0,
            comments=f"{dimension}匹配度: {score*100:.1f}%"
        ))
    
    # 构建建议
    suggestions = [
        "候选人已通过初步筛选，建议安排面试",
        "重点关注候选人的实际项目经验",
        "可以进一步了解候选人的职业发展规划"
    ]
    
    screening_result = ScreeningResult(
        passed=True,
        final_score=final_score,
        threshold_score=threshold_score,
        feedback=feedback_items,
        suggestions=suggestions
    )
    
    # 将中文推荐值映射为英文值
    def map_recommendation_to_english(chinese_recommendation):
        mapping = {
            '推荐进入面试': 'recommended',
            '有条件推荐': 'conditional',
            '暂不推荐': 'not_recommended'
        }
        return mapping.get(chinese_recommendation, 'recommended')
    
    # 构建候选人摘要
    candidate_summary = CandidateSummary(
        candidate_name=ai_summary.get('candidate_name', '未知'),
        match_score=ai_summary.get('match_score', final_score),
        core_skills_matched=ai_summary.get('core_skills_matched', []),
        soft_skills_detected=ai_summary.get('soft_skills_detected', []),
        education_summary=ai_summary.get('education_summary', ''),
        experience_summary=ai_summary.get('experience_summary', ''),
        resume_file_url=resume_url,
        interview_recommendation=map_recommendation_to_english(ai_summary.get('interview_recommendation', '推荐进入面试')),
        highlights=ai_summary.get('highlights', [])
    )
    
    return {
        "candidate_summary": candidate_summary.to_dict(),
        "screening_result": screening_result.to_dict(),
        "match_score": final_score,
        "final_score": final_score,
        "passed": True
    }

def _create_failed_report(
    final_score: float,
    threshold_score: float,
    matcher_result: Dict[str, Any]
    ) -> dict:
    """创建未通过筛选的报告"""
    
    # 构建反馈项目
    feedback_items = []
    for dimension, score in matcher_result.get('details', {}).items():
        feedback_items.append(FeedbackItem(
            dimension=dimension,
            score=score * 100,  # 转换为百分比
            max_score=100.0,
            comments=f"{dimension}匹配度: {score*100:.1f}%"
        ))
    
    # 构建建议
    suggestions = [
        "建议候选人提升相关技能",
        "可以考虑其他更适合的职位",
        "建议候选人完善简历内容"
    ]
    
    screening_result = ScreeningResult(
        passed=False,
        final_score=final_score,
        threshold_score=threshold_score,
        feedback=feedback_items,
        suggestions=suggestions
    )
    
    return {
        "screening_result": screening_result.to_dict(),
        "match_score": final_score,
        "final_score": final_score,
        "passed": False
    } 